package org.ecype.diego;

import java.lang.reflect.Field;

import org.ecype.diego.sqlite.DatabaseHelper;

import android.content.ContentResolver;
import android.content.ContentUris;
import android.content.ContentValues;
import android.database.Cursor;
import android.net.Uri;
import android.text.TextUtils;
import android.util.Log;
import androidx.persistence.Id;
import androidx.persistence.PersistenceException;

public class EntityProcessor extends AbstractUriProcessor {

	private final String name;
	private final String type;
	private DatabaseHelper helper;
	protected ContentResolver resolver;

	protected EntityProcessor(Entity entity, String type) {
		name = entity.getName();
		this.type = type;
	}

	@Override
	public void setup(ContractContentProvider provider, Field field) {
		super.setup(provider, field);
		helper = provider.getHelper();
		resolver = provider.getContext().getContentResolver();
	}

	protected Uri insertHelper(Uri uri, Uri notifyUri, ContentValues values) {
		long id = helper.getWritableDatabase().insert(name, null, values);
		if (id > 0) {
			resolver.notifyChange(notifyUri, null);
			return ContentUris.withAppendedId(uri, id);
		} else {
			Cursors.dump(values);
			throw new PersistenceException("Could not insert values for uri " + uri);
		}

	}
	
	protected int bulkInsertHelper(Uri uri, Uri notifyUri, ContentValues[] values) {
		helper.getWritableDatabase().beginTransaction();
		try {
    		int count = 0;
    		for (ContentValues val : values) {
    			long id = helper.getWritableDatabase().insert(name, null, val);
    			if (id > 0) {
    				count++;
    			} else {
    				Cursors.dump(val);
    				throw new PersistenceException("Could not insert values for uri " + uri);
    			}
    		}
    		helper.getWritableDatabase().setTransactionSuccessful();
    		return count;
		} finally {
			helper.getWritableDatabase().endTransaction();
			resolver.notifyChange(notifyUri, null);
		}
	}

	@Override
	public String getType(Uri uri) {
		return type + name;
	}

	protected Cursor queryHelper(Uri uri, Uri notifyUri, String[] projection, String selection, String[] selectionArgs, String sortOrder) {
		Cursor query = helper.getReadableDatabase().query(name, projection, selection, selectionArgs, null, null, sortOrder);
		query.setNotificationUri(resolver, notifyUri);
		return query;
	}

	protected int deleteHelper(Uri uri, Uri notifyUri, String selection, String[] selectionArgs) {
		int count = helper.getWritableDatabase().delete(name, selection, selectionArgs);
		resolver.notifyChange(notifyUri, null);
		return count;
	}

	protected int updateHelper(Uri uri, Uri notifyUri, ContentValues values, String selection, String[] selectionArgs) {
		int count = helper.getWritableDatabase().update(name, values, selection, selectionArgs);
		resolver.notifyChange(notifyUri, null);
		return count;
	}

	protected static String whereIdIs(Uri uri) {
		return Id.COLUMN_NAME + " = " + parseId(uri);
	}

	protected static long parseId(Uri uri) {
		return Long.parseLong(uri.getPathSegments().get(1));
	}

	protected static String appendParentId(Uri uri, String selection, Reference reference) {
		if (TextUtils.isEmpty(selection)) {
			selection = "";
		} else {
			selection = "(" + selection + ") AND ";
		}
		selection += reference.getLinkToParent() + " = " + parseId(uri);
		Log.d("SQL", selection);
		return selection;
	}
}
